﻿using MyMes.Infrastructure;
using MyMES.Dto;
using MyMES.IServices.WorkforceManagement;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using VOL.Entity.DomainModels;
using Microsoft.EntityFrameworkCore;
using VOL.Core.Utilities.Response;
using VOL.Core.Extensions;

using VOL.Entity.DomainModels.WorkforceManagement;

namespace MyMES.Services.WorkforceManagement
{
    public class WorkforceService : IWorkforceService
    {
        private readonly IBaseRepository<WorkforceDetail> _workforceDetailRepository;
        private readonly IBaseRepository<Holidays> _holidaysRepository;
        private readonly IBaseRepository<VOL.Entity.DomainModels.WorkforceManagement.Team> _teamRepository;
        private readonly IBaseRepository<TeamTypes> _teamTypesRepository;

        public WorkforceService(IBaseRepository<WorkforceDetail> workforceDetailRepository, IBaseRepository<Holidays> holidaysRepository, IBaseRepository<VOL.Entity.DomainModels.WorkforceManagement.Team> teamRepository, IBaseRepository<TeamTypes> teamTypesRepository)
        {
            _workforceDetailRepository = workforceDetailRepository;
            _holidaysRepository = holidaysRepository;
            _teamRepository = teamRepository;
            _teamTypesRepository = teamTypesRepository;
        }

        /// <summary>
        /// 获取班组列表
        /// </summary>
        /// <returns></returns>
        public async Task<WebResponseContent> GetTeamList()
        {
            WebResponseContent response = new WebResponseContent();
            try
            {
                var teams = await _teamRepository.GetAll().ToListAsync();
                return response.OK("获取班组列表成功", teams);
            }
            catch (Exception ex)
            {
                return response.Error($"获取班组列表失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 获取班组类型列表
        /// </summary>
        /// <returns></returns>
        public async Task<WebResponseContent> GetTeamTypeList()
        {
            WebResponseContent response = new WebResponseContent();
            try
            {
                var teamTypes = await _teamTypesRepository.GetAll().ToListAsync();
                return response.OK("获取班组类型列表成功", teamTypes);
            }
            catch (Exception ex)
            {
                return response.Error($"获取班组类型列表失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 获取工作日历
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public async Task<WebResponseContent> GetWorkforceCalendar(GetWorkforceCalendarDto dto)
        {
            WebResponseContent response = new WebResponseContent();

            try
            {
                // 直接查询指定月份的假期数据
                var holidays = await _holidaysRepository.GetAll()
                    .Where(h => h.HolidaysTime.HasValue && 
                           h.HolidaysTime.Value.Year == dto.QueryYear && 
                           h.HolidaysTime.Value.Month == dto.QueryMonth)
                    .ToListAsync();

                Console.WriteLine($"找到假期数据：{holidays.Count}条");

                // 查询所有班组信息，不过滤
                var allTeams = await _teamRepository.GetAll().ToListAsync();
                Console.WriteLine($"找到班组：{allTeams.Count}条");

                // 查询指定月份的排班数据
                var schedules = await _workforceDetailRepository.GetAll()
                    .Where(s => s.WorkDate.Year == dto.QueryYear && 
                           s.WorkDate.Month == dto.QueryMonth)
                    .ToListAsync();

                Console.WriteLine($"找到排班数据：{schedules.Count}条");

                // 如果需要按班组筛选
                if (dto.QueryGroupId.HasValue && dto.QueryGroupId.Value > 0)
                {
                    schedules = schedules.Where(s => s.GroupId == dto.QueryGroupId.Value).ToList();
                }

                // 创建日历数据
                var calendarData = CreateCalendarData(dto.QueryYear, dto.QueryMonth, holidays, schedules, allTeams);

                // 创建返回结果
                var result = new WorkforceCalendarResultDto
                {
                    Year = dto.QueryYear,
                    Month = dto.QueryMonth,
                    CalendarData = calendarData
                };

                return response.OK("获取工作日历数据成功", result);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"获取工作日历出错: {ex.Message}");
                Console.WriteLine($"堆栈信息: {ex.StackTrace}");
                return response.Error($"获取工作日历数据失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 创建日历数据
        /// </summary>
        private List<WorkforceCalendarDto> CreateCalendarData(int year, int month, List<Holidays> holidays, List<WorkforceDetail> schedules, List<Team> teams)
        {
            var result = new List<WorkforceCalendarDto>();

            // 确定月份的起始和结束日期
            DateTime startDate = new DateTime(year, month, 1);
            DateTime endDate = startDate.AddMonths(1).AddDays(-1);

            // 为每一天创建日历数据
            for (DateTime day = startDate; day <= endDate; day = day.AddDays(1))
            {
                // 检查是否为节假日
                var holiday = holidays.FirstOrDefault(h => h.HolidaysTime?.Date == day.Date);
                var isHoliday = holiday != null;
                var isWeekend = (day.DayOfWeek == DayOfWeek.Saturday || day.DayOfWeek == DayOfWeek.Sunday);

                // 获取当天的排班数据
                var daySchedules = schedules.Where(s => s.WorkDate.Date == day.Date).ToList();

                // 创建日历项
                var calendarDay = new WorkforceCalendarDto
                {
                    Date = day,
                    Day = day.Day,
                    DayOfWeek = ((int)day.DayOfWeek == 0) ? 7 : (int)day.DayOfWeek, // 转换为1-7表示周一到周日
                    IsHoliday = isHoliday || isWeekend,
                    HolidayName = isHoliday ? "节假日" : (isWeekend ? "周末" : ""),
                    HolidayType = holiday?.HolidaysType ?? (isWeekend ? 2 : 0), // 1=法定节假日，2=休息日
                    IsWorkDay = !isHoliday && !isWeekend && daySchedules.Any(s => s.WorkShift >= 0),
                    LunarDate = "", // 暂不实现农历
                    Groups = new List<WorkforceGroupDto>()
                };

                // 添加班组数据
                foreach (var team in teams)
                {
                    // 查找该班组当天的排班数据
                    var schedule = daySchedules.FirstOrDefault(s => s.GroupId == team.Id);

                    // 如果有排班数据，使用实际数据；否则创建默认数据
                    WorkforceGroupDto groupDto;
                    if (schedule != null)
                    {
                        groupDto = new WorkforceGroupDto
                        {
                            GroupId = team.Id,
                            GroupName = team.TeamName,
                            GroupType = GetGroupTypeValue(team.TeamType),
                            Status = schedule.Status,
                            Remark = team.Remark ?? ""
                        };
                    }
                    else
                    {
                        // 默认状态：周末和节假日休息，工作日上班
                        int status = (isHoliday || isWeekend) ? 0 : 1;

                        groupDto = new WorkforceGroupDto
                        {
                            GroupId = team.Id,
                            GroupName = team.TeamName,
                            GroupType = GetGroupTypeValue(team.TeamType),
                            Status = status,
                            Remark = team.Remark ?? ""
                        };
                    }

                    calendarDay.Groups.Add(groupDto);
                }

                result.Add(calendarDay);
            }

            return result;
        }

        /// <summary>
        /// 将班组类型名称转换为整数值，用于前端展示
        /// </summary>
        private int GetGroupTypeValue(string teamType)
        {
            if (string.IsNullOrEmpty(teamType))
                return 1; // 默认为1

            // 根据班组类型返回不同的值，用于前端区分颜色
            switch (teamType.Trim())
            {
                case "注塑":
                    return 1;
                case "机加工":
                    return 2;
                case "组装":
                    return 3;
                case "仓库":
                    return 4;
                default:
                    return 1;
            }
        }

        /// <summary>
        /// 获取农历日期 (简单实现或使用第三方库)
        /// </summary>
        private string GetLunarDate(DateTime date)
        {
            // 这里可以使用中国农历转换库或其他方法获取农历日期
            // 简单实现，实际项目中应当使用专业的农历转换库
            return ""; // 暂时返回空字符串
        }

        /// <summary>
        /// 返回硬编码的测试数据
        /// </summary>
        private WebResponseContent GetTestData(GetWorkforceCalendarDto dto)
        {
            WebResponseContent response = new WebResponseContent();

            // 创建返回结果对象
            var result = new WorkforceCalendarResultDto
            {
                Year = dto.QueryYear,
                Month = dto.QueryMonth,
                CalendarData = new List<WorkforceCalendarDto>()
            };

            // 生成7月测试数据
            DateTime startDate = new DateTime(2023, 7, 1);
            DateTime endDate = new DateTime(2023, 7, 31);

            // 定义班组
            var teams = new List<(int Id, string Name, string Type)>
            {
                (1, "注塑一组", "注塑"),
                (2, "注塑二组", "注塑"),
                (3, "机加工一组", "机加工"),
                (4, "机加工二组", "机加工"),
                (5, "组装一组", "组装"),
                (6, "组装二组", "组装"),
                (7, "仓库一组", "仓库"),
                (8, "仓库二组", "仓库")
            };

            // 定义假期
            var holidays = new List<DateTime>
            {
                new DateTime(2023, 7, 1),
                new DateTime(2023, 7, 2),
                new DateTime(2023, 7, 8),
                new DateTime(2023, 7, 9),
                new DateTime(2023, 7, 15),
                new DateTime(2023, 7, 16),
                new DateTime(2023, 7, 22),
                new DateTime(2023, 7, 23),
                new DateTime(2023, 7, 29),
                new DateTime(2023, 7, 30)
            };

            // 填充日历数据
            for (var day = startDate; day <= endDate; day = day.AddDays(1))
            {
                var isHoliday = holidays.Contains(day);
                var isWeekend = (day.DayOfWeek == DayOfWeek.Saturday || day.DayOfWeek == DayOfWeek.Sunday);

                var calendarDay = new WorkforceCalendarDto
                {
                    Date = day,
                    Day = day.Day,
                    DayOfWeek = ((int)day.DayOfWeek == 0) ? 7 : (int)day.DayOfWeek,
                    IsHoliday = isHoliday || isWeekend,
                    HolidayName = "",
                    HolidayType = isWeekend ? 2 : 0,
                    IsWorkDay = !isWeekend && !isHoliday,
                    LunarDate = "",
                    Groups = new List<WorkforceGroupDto>()
                };

                // 为每个班组添加数据
                foreach (var team in teams)
                {
                    int status;
                    // 根据规则确定班组的上班状态
                    if (isWeekend || isHoliday)
                    {
                        status = 0; // 休息
                    }
                    else
                    {
                        // 注塑组的排班规则：按周轮换
                        if (team.Id <= 2)
                        {
                            int weekNumber = ((day.Day - 1) / 7) + 1;
                            status = (weekNumber % 2 == 1) ?
                                (team.Id == 1 ? 1 : 0) : // 奇数周一组上班二组休息
                                (team.Id == 2 ? 1 : 0);  // 偶数周二组上班一组休息
                        }
                        // 机加工组的排班规则：按天轮换
                        else if (team.Id <= 4)
                        {
                            status = (day.Day % 2 == 1) ?
                                (team.Id == 3 ? 1 : 0) : // 奇数日一组上班二组休息
                                (team.Id == 4 ? 1 : 0);  // 偶数日二组上班一组休息
                        }
                        // 组装组的排班规则：按月轮换
                        else if (team.Id <= 6)
                        {
                            status = (team.Id == 6) ? 1 : 0; // 7月份由二组负责
                        }
                        // 仓库组的排班规则：按天轮换
                        else
                        {
                            status = (day.Day % 2 == 1) ?
                                (team.Id == 7 ? 1 : 0) : // 奇数日一组上班二组休息
                                (team.Id == 8 ? 1 : 0);  // 偶数日二组上班一组休息
                        }
                    }

                    calendarDay.Groups.Add(new WorkforceGroupDto
                    {
                        GroupId = team.Id,
                        GroupName = team.Name,
                        GroupType = GetGroupTypeValue(team.Type),
                        Status = status,
                        Remark = $"{team.Type}类"
                    });
                }

                result.CalendarData.Add(calendarDay);
            }

            return response.OK("获取工作日历数据成功", result);
        }
    }
}
